/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bsc.war.service;

import bsc.ejb.entity.Comparator;
import bsc.ejb.entity.ComparatorDimensionalCut;
import bsc.ejb.entity.DimensionMember;
import bsc.ejb.entity.DimensionalCut;
import bsc.ejb.entity.Person;
import bsc.ejb.entity.PersonScoreDomain;
import bsc.ejb.entity.Pointer;
import bsc.ejb.entity.SRM;
import bsc.ejb.entity.SRMTopic;
import bsc.ejb.entity.ScoreDomain;
import bsc.ejb.entity.Settings;
import bsc.ejb.entity.Task;
import bsc.ejb.metadata.Comparation;
import bsc.ejb.metadata.Comparation.Type;
import bsc.ejb.metadata.Framework;
import bsc.ejb.metadata.License;
import bsc.war.delegate.DelegateBSC;
import bsc.war.factory.Factory;
import com.towel.math.Expression;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

/**
 *
 * @author memozac
 */
public class BSCUtils {

    public static final String ENCRYPT_HASH_KEY = "019283KJ123BV123T12";
    private static final String VARIABLE_CONS = "P";
    //private static final String VARIABLE_PIVOT = "P";
    private static final String VARIABLE_EXP = "(" + VARIABLE_CONS + "[0-9]+)";

    public static List<Date> isParentComparatorDimenalCutDatesExecutable(DelegateBSC delegate, Pointer pointer, Comparation comparation, List<Date> dates) {
        List<Date> datesResult = new ArrayList<Date>();
        DimensionalCut rootDimensionalCut = BSCUtils.getRootDimensionalCut(delegate, pointer);
        //System.out.println("El dimensionalCutRoot es: " + rootDimensionalCut.getIdScoreCard());
        List<DimensionMember> dimensionMembers = delegate.findDimensionMember(rootDimensionalCut);

        //Members of members boolean
        Map<DimensionMember, Boolean> cutMembersSons = ScoreCardUtils.reviewMembersSons(dimensionMembers, delegate);
        //List<Date> dates = ScoreCardUtils.generateDatesRange(initDate, endDate, pointer);

        for (Date date : dates) {

            if (BSCUtils.isParentComparatorDimenalCutExecutable(delegate, pointer, rootDimensionalCut,dimensionMembers, cutMembersSons, comparation, date)) {
                datesResult.add(date);
            }

        }
        return datesResult;
    }

    public static boolean isParentComparatorDimenalCutExecutable(DelegateBSC delegate, Pointer pointer, Comparation comparation, List<Date> dates) {
        DimensionalCut rootDimensionalCut = BSCUtils.getRootDimensionalCut(delegate, pointer);
        List<DimensionMember> dimensionMembers = delegate.findDimensionMember(rootDimensionalCut);

        //Members of members boolean
        Map<DimensionMember, Boolean> cutMembersSons = ScoreCardUtils.reviewMembersSons(dimensionMembers, delegate);
        //List<Date> dates = ScoreCardUtils.generateDatesRange(initDate, endDate, pointer);

        for (Date date : dates) {
            List<DimensionMember> rootDimensionMembers = delegate.findDimensionMember(rootDimensionalCut);
            for (DimensionMember dimensionMember : rootDimensionMembers) {
                if (!BSCUtils.isParentComparatorDimenalCutExecutable(delegate, pointer, rootDimensionalCut,dimensionMembers, cutMembersSons, comparation, date)) {
                    return false;
                }
            }
        }
        return true;
    }

    private static boolean isParentComparatorDimenalCutExecutable(DelegateBSC delegate, Pointer pointer, DimensionalCut rootDimensionalCut,List<DimensionMember> rootDimensionMembersVerify ,Map<DimensionMember, Boolean> cutMembersSons, Comparation comparation, Date date) {
        Boolean hasSons = true;
        boolean hasRegisterFinal = true;

        //List<DimensionMember> rootDimensionMembersVerify = delegate.findDimensionMember(rootDimensionalCut);
        int cont = 0;
        //System.out.println("El dimensionalcut: " + rootDimensionalCut.getIdScoreCard());
        //System.out.println("Su mapa: " + cutMembersSons);
        for (int i = 0; i < rootDimensionMembersVerify.size(); i++) {
            DimensionMember dimensionMember = rootDimensionMembersVerify.get(i);
            //System.out.println("El dimension Member a revisar es: " + dimensionMember.getIdDimensionMember());
            if (cutMembersSons.get(dimensionMember) == true) {
                
                List<DimensionalCut> dimensionalCutsChildren = getDimensionalCutChildren(delegate, pointer, rootDimensionalCut, dimensionMember);
                //System.out.println("Entre al caso de que TENGO HIJOS: " + dimensionalCutsChildren.size());
                boolean hasRegister = true;
                for (DimensionalCut dimensionalCut : dimensionalCutsChildren) {
                    List<DimensionMember> dimensionMembers = delegate.findDimensionMember(dimensionalCut);
                    Map<DimensionMember, Boolean> cutMembersSonsN = ScoreCardUtils.reviewMembersSons(dimensionMembers, delegate);
                    hasRegister = BSCUtils.isParentComparatorDimenalCutExecutable(delegate, pointer, dimensionalCut,dimensionMembers, cutMembersSonsN, comparation, date);
                    if (!hasRegister) {
                        return false;
                    }
                }
                return hasRegister;
            } else {
                cont++;
            }
        }

        if (cont == rootDimensionMembersVerify.size()) {
            hasSons = false;
        }

        if (hasSons == null || !hasSons) {
            Comparator comparator = delegate.findComparator(pointer, comparation);
            ComparatorDimensionalCut comparatorDimensionalCut = delegate.findComparatorDimensionalCut(comparator, rootDimensionalCut, date);
            /*
            //DEBUG
            if (comparatorDimensionalCut == null) {
                System.out.println("No tiene datos!!!!!!");
            } else {
                System.out.println("Si tiene datos!!!!!!");
            }*/
            //return comparatorDimensionalCut != null;
            return comparatorDimensionalCut != null ? true : false;
        }
        return hasRegisterFinal;
    }

    public static void setParentComparatorDimensionalCut(DelegateBSC delegate, Pointer pointer, Comparation comparation, List<Date> dates) {
        DimensionalCut rootDimensionalCut = BSCUtils.getRootDimensionalCut(delegate, pointer);
        List<DimensionMember> dimensionMembers = delegate.findDimensionMember(rootDimensionalCut);

        //Members of members boolean
        Map<DimensionMember, Boolean> cutMembersSons = ScoreCardUtils.reviewMembersSons(dimensionMembers, delegate);
        //List<Date> dates = ScoreCardUtils.generateDatesRange(initDate, endDate, pointer);
        //System.out.println("El tamaño de datos es: " + dates.size());
        for (Date date : dates) {
            //System.out.println("La fecha a consolidar es: " + date.toString());
            List<DimensionMember> rootDimensionMembers = delegate.findDimensionMember(rootDimensionalCut);
            for (DimensionMember dimensionMember : rootDimensionMembers) {
                //if (BSCUtils.isParentComparatorDimenalCutExecutable(delegate, pointer, rootDimensionalCut, cutMembersSons, comparation, date)) {
                    BSCUtils.setParentComparatorDimensionalCut(delegate, pointer, rootDimensionalCut, rootDimensionMembers.size(), dimensionMember, cutMembersSons, comparation, date);
                //}
            }
        }
    }

    private static Double setParentComparatorDimensionalCut(DelegateBSC delegate, Pointer pointer, DimensionalCut rootDimensionalCut, double rootDimensionalCutSize,  DimensionMember rootDimensionMember, Map<DimensionMember, Boolean> cutMembersSons, Comparation comparation, Date date) {
        Boolean hasSons = cutMembersSons.get(rootDimensionMember);
        
        if (hasSons == null || !hasSons) {
            Comparator comparator = delegate.findComparator(pointer, comparation);
            //System.out.println("Comparator info: " + comparator.getComparation().getName());
            ComparatorDimensionalCut comparatorDimensionalCut = delegate.findComparatorDimensionalCut(comparator, rootDimensionalCut, date);
            //System.out.println("ID deel ComparatorDimensionalCut: " + comparatorDimensionalCut.getIdComparatorDimensionalCut());
            return comparatorDimensionalCut != null ? comparatorDimensionalCut.getRegister() : 0.0D;

        } else {

            List<DimensionalCut> dimensionalCutsChildren = getDimensionalCutChildren(delegate, pointer, rootDimensionalCut, rootDimensionMember);
            Double register = 0.0D;
            for (DimensionalCut dimensionalCut : dimensionalCutsChildren) {
                List<DimensionMember> rootDimensionMembers = delegate.findDimensionMember(dimensionalCut);
                Map<DimensionMember, Boolean> cutMembersSonsSons = ScoreCardUtils.reviewMembersSons(rootDimensionMembers, delegate);
                for (DimensionMember dimensionMember : rootDimensionMembers) {
                    register += setParentComparatorDimensionalCut(delegate, pointer, dimensionalCut, rootDimensionalCutSize, dimensionMember, cutMembersSonsSons, comparation, date);
                    //System.out.println("Sume los datos");
                }
            }
            
            register = register / rootDimensionalCutSize;
            
            //Check type of consolidate
            Settings settings = pointer.getSettings();
            if (settings.getOperationData() == Settings.OperationData.CONSOLIDATEAVG) {
                register = register / dimensionalCutsChildren.size();
            }

            register= BSCUtils.roundNumber(register, 2);

            Comparator comparator = delegate.findComparator(pointer, comparation);
            ComparatorDimensionalCut comparatorDimensionalCut = delegate.findComparatorDimensionalCut(comparator, rootDimensionalCut, date);
            if (comparatorDimensionalCut != null) {
                comparatorDimensionalCut.setRegister(register);

                delegate.updateComparatorDimensionalCut(comparatorDimensionalCut);
            } else {
                comparatorDimensionalCut = (ComparatorDimensionalCut) Factory.getBean("ComparatorDimensionalCut");
                comparatorDimensionalCut.setComparator(comparator);
                comparatorDimensionalCut.setDimensionalCut(rootDimensionalCut);
                comparatorDimensionalCut.setRegister(register);
                comparatorDimensionalCut.setRegisterDate(date);

                delegate.createComparatorDimensionalCut(comparatorDimensionalCut);
            }
            return register;
        }
    }

    private static List<DimensionalCut> getDimensionalCutChildren(DelegateBSC delegate, Pointer pointer, DimensionalCut rootDimensionalCut, DimensionMember rootDimensionMember) {
        List<DimensionalCut> dimensionalCuts = delegate.findDimensionalCut(pointer);
        List<DimensionMember> rootDimensionMembers = delegate.findDimensionMember(rootDimensionalCut);
        List<DimensionalCut> dimensionalCutsChilden = new ArrayList<DimensionalCut>();

        for (DimensionalCut dimensionalCut : dimensionalCuts) {

            List<DimensionMember> dimensionMembers = delegate.findDimensionMember(dimensionalCut);


            if (ScoreCardUtils.reviewRootAdvance(dimensionMembers, rootDimensionMembers, rootDimensionMember)) {
                dimensionalCutsChilden.add(dimensionalCut);
            }
        }
        return dimensionalCutsChilden;
    }

    private static DimensionalCut getRootDimensionalCut(DelegateBSC delegate, Pointer pointer) {

        //Find the cuts of the pointer
        List<DimensionalCut> dimensionalCuts = delegate.findDimensionalCut((Pointer) pointer);

        for (DimensionalCut dimensionalCut : dimensionalCuts) {
            List<DimensionMember> dimensionMembers = delegate.findDimensionMember(dimensionalCut);

            if (ScoreCardUtils.reviewRoot(dimensionMembers)) {
                return dimensionalCut;
            }
        }
        return null;
    }

    public static void setComparatorDimensionalCut(DelegateBSC delegate, Comparation comparation, Pointer pointer, Date initDate, Date endDate) {
        String mathOperation = pointer.getSettings().getDimensionalCutOperation();
        if (mathOperation == null) {
            return;
        }
        Comparator comparator = delegate.findComparator(pointer, comparation);

        List<Date> dates = ScoreCardUtils.generateDatesRange(initDate, endDate, pointer);
        List<Pointer> pointers = BSCUtils.getPointers(delegate, mathOperation);
        HashMap<Pointer, HashMap<Date, HashMap<DimensionalCut, Double>>> pointerDateDimensionalCutValues = BSCUtils.getComparatorDimensionalCutValue(delegate, pointers, dates, comparation, pointer);
        for (Date date : dates) {
            //System.out.println("fecha: " + date.toString());
            List<DimensionalCut> dimensionalCuts = delegate.findDimensionalCut(pointer);
            for (DimensionalCut dimensionalCut : dimensionalCuts) {
                Expression exp = new Expression(mathOperation);
                boolean executeOperation = true;
                for (Pointer foreignPointer : pointers) {
                    String variable = BSCUtils.VARIABLE_CONS + foreignPointer.getIdScoreCard();
                    DimensionalCut foreignDimensionalCut = BSCUtils.getDimensionalCut(delegate, dimensionalCut, foreignPointer);
                    //System.out.println("El id del dimensional cut es: " + foreignDimensionalCut.getIdDimensionalCut());
                    //HashMap<DimensionalCut, Double> mapita = pointerDateDimensionalCutValues.get(date);
                    //System.out.println("Mapita!!!: " + mapita.toString());

                    Double value = pointerDateDimensionalCutValues.get(foreignPointer).get(date).get(foreignDimensionalCut);

                    //System.out.println("Variable: " + variable);
                    //System.out.println("Value: " + value);

                    if (value != null && mathOperation.contains(variable)) {
                        //System.out.println("Variable: " + variable);
                        //System.out.println("Value: " + value);
                        exp.setVariable(variable, value);
                    } else {
                        executeOperation = false;
                        break;
                    }
                }
                if (executeOperation) {
                    Double register = exp.resolve();
                    if (!register.isNaN() && !register.isInfinite()) {
                        ComparatorDimensionalCut comparatorDimensionalCut = delegate.findComparatorDimensionalCut(comparator, dimensionalCut, date);
                        if (comparatorDimensionalCut != null) {
                            comparatorDimensionalCut.setRegister(register);

                            delegate.updateComparatorDimensionalCut(comparatorDimensionalCut);
                        } else {
                            comparatorDimensionalCut = (ComparatorDimensionalCut) Factory.getBean("ComparatorDimensionalCut");
                            comparatorDimensionalCut.setComparator(comparator);
                            comparatorDimensionalCut.setDimensionalCut(dimensionalCut);
                            comparatorDimensionalCut.setRegister(register);
                            comparatorDimensionalCut.setRegisterDate(date);

                            delegate.createComparatorDimensionalCut(comparatorDimensionalCut);
                        }
                    }

                }
            }
        }
    }

    public static void setComparatorDimensionalCut(DelegateBSC delegate, Comparation comparation, Pointer pointer, List<Date> dates) {
        String mathOperation = pointer.getSettings().getDimensionalCutOperation();
        if (mathOperation == null) {
            return;
        }
        Comparator comparator = delegate.findComparator(pointer, comparation);

        //List<Date> dates = ScoreCardUtils.generateDatesRange(initDate, endDate, pointer);
        List<Pointer> pointers = BSCUtils.getPointers(delegate, mathOperation);
        HashMap<Pointer, HashMap<Date, HashMap<DimensionalCut, Double>>> pointerDateDimensionalCutValues = BSCUtils.getComparatorDimensionalCutValue(delegate, pointers, dates, comparation, pointer);
        for (Date date : dates) {
            //System.out.println("fecha: " + date.toString());
            List<DimensionalCut> dimensionalCuts = delegate.findDimensionalCut(pointer);
            for (DimensionalCut dimensionalCut : dimensionalCuts) {
                Expression exp = new Expression(mathOperation);
                boolean executeOperation = true;
                for (Pointer foreignPointer : pointers) {
                    String variable = BSCUtils.VARIABLE_CONS + foreignPointer.getIdScoreCard();
                    DimensionalCut foreignDimensionalCut = BSCUtils.getDimensionalCut(delegate, dimensionalCut, foreignPointer);
                    //System.out.println("El id del dimensional cut es: " + foreignDimensionalCut.getIdDimensionalCut());
                    //HashMap<DimensionalCut, Double> mapita = pointerDateDimensionalCutValues.get(date);
                    //System.out.println("Mapita!!!: " + mapita.toString());

                    Double value = pointerDateDimensionalCutValues.get(foreignPointer).get(date).get(foreignDimensionalCut);

                    //System.out.println("Variable: " + variable);
                    //System.out.println("Value: " + value);

                    if (value != null && mathOperation.contains(variable)) {
                        //System.out.println("Variable: " + variable);
                        //System.out.println("Value: " + value);
                        exp.setVariable(variable, value);
                    } else {
                        executeOperation = false;
                        break;
                    }
                }
                if (executeOperation) {
                    Double register = exp.resolve();
                    if (!register.isNaN() && !register.isInfinite()) {

                        //Format of the result
                        NumberFormat formatter = new DecimalFormat("#0.00");
                        String stringRegister = formatter.format(register);
                        register = Double.parseDouble(stringRegister);

                        ComparatorDimensionalCut comparatorDimensionalCut = delegate.findComparatorDimensionalCut(comparator, dimensionalCut, date);
                        if (comparatorDimensionalCut != null) {
                            comparatorDimensionalCut.setRegister(register);

                            delegate.updateComparatorDimensionalCut(comparatorDimensionalCut);
                        } else {
                            comparatorDimensionalCut = (ComparatorDimensionalCut) Factory.getBean("ComparatorDimensionalCut");
                            comparatorDimensionalCut.setComparator(comparator);
                            comparatorDimensionalCut.setDimensionalCut(dimensionalCut);
                            comparatorDimensionalCut.setRegister(register);
                            comparatorDimensionalCut.setRegisterDate(date);

                            delegate.createComparatorDimensionalCut(comparatorDimensionalCut);
                        }
                    }

                }
            }
        }
    }

    private static List<Pointer> getPointers(DelegateBSC delegate, String mathOperation) {
        mathOperation = ScoreCardUtils.cleanOperation(mathOperation);

        List<Pointer> comparators = new ArrayList<Pointer>();
        String[] operationCrap = mathOperation.split(BSCUtils.VARIABLE_EXP);

        for (String crap : operationCrap) {
            if (!"".equals(crap)) {
                mathOperation = mathOperation.replace(crap, ",");
            }
        }
        for (String pointerVar : mathOperation.split(",")) {
            if (pointerVar != null && !"".equals(pointerVar) && pointerVar.contains(BSCUtils.VARIABLE_CONS) && ScoreCardUtils.isPositiveNumber(pointerVar.replace(BSCUtils.VARIABLE_CONS, ""))) {
                Long idPointer = Long.parseLong(pointerVar.replace(BSCUtils.VARIABLE_CONS, ""));
                //Pointer pointer = delegate.findPointer(idPointer);
                Pointer pointer = (Pointer) delegate.findScoreCard(idPointer);
                if (pointer != null) {
                    comparators.add(pointer);
                }

            }
        }

        return comparators;
    }

    private static DimensionalCut getDimensionalCut(DelegateBSC delegate, DimensionalCut dimensionalCut, Pointer pointer) { // miguel
        DimensionalCut dimensionalCutResult = null;
        //Members of the central pointer
        List<DimensionMember> dimensionMembers = delegate.findDimensionMember(dimensionalCut);

        //Dimensionalcuts of the variable
        List<DimensionalCut> dimensionalCutsVariable = delegate.findDimensionalCut(pointer);
        for (int i = 0; i < dimensionalCutsVariable.size(); i++) {
            DimensionalCut dimensionalCutVariable = dimensionalCutsVariable.get(i);
            List<DimensionMember> dimensionMembersVariable = delegate.findDimensionMember(dimensionalCutVariable);
            if (reviewDimensionalCuts(dimensionMembers, dimensionMembersVariable) == true) {
                dimensionalCutResult = dimensionalCutVariable;
            }
        }
        return dimensionalCutResult;
    }

    private static boolean reviewDimensionalCuts(List<DimensionMember> dimensionMembers, List<DimensionMember> dimensionMembersVariable) {
        boolean comparation = false;
        int count = 0;
        for (int i = 0; i < dimensionMembersVariable.size(); i++) {
            if (dimensionMembers.contains(dimensionMembersVariable.get(i))) {
                count++;
            }
        }
        if (count == dimensionMembers.size()) {
            comparation = true;
        }
        return comparation;
    }

    public static HashMap<Pointer, HashMap<Date, HashMap<DimensionalCut, Double>>> getComparatorDimensionalCutValue(DelegateBSC delegate, List<Pointer> pointers, List<Date> dates, Comparation comparation, Pointer pointer) {
        HashMap<Pointer, HashMap<Date, HashMap<DimensionalCut, Double>>> pointerDateDimensionalCutValues = new HashMap<Pointer, HashMap<Date, HashMap<DimensionalCut, Double>>>();

        List<DimensionalCut> dimensionalCuts = delegate.findDimensionalCut(pointer);
        for (Pointer foreignPointer : pointers) {

            HashMap<Date, HashMap<DimensionalCut, Double>> dateDimensionalCutValues = new HashMap<Date, HashMap<DimensionalCut, Double>>();
            Comparator foreignComparator = delegate.findComparator(foreignPointer, comparation);
            for (Date date : dates) {
                //System.out.println("LA SUPER FECHA ES: " + date.toString());
                HashMap<DimensionalCut, Double> dimensionalCutValues = new HashMap<DimensionalCut, Double>();
                for (DimensionalCut dimensionalCut : dimensionalCuts) {
                    //DimensionalCut foreignDimensionalCut = BSCUtils.getDimensionalCut(delegate, dimensionalCut, pointer);
                    DimensionalCut foreignDimensionalCut = BSCUtils.getDimensionalCut(delegate, dimensionalCut, foreignPointer);
                    //System.out.println("Dimensional Cut: " + dimensionalCut.getIdDimensionalCut());
                    if (foreignDimensionalCut != null) {
                        //System.out.println("Foreign Dimensional Cut: " + foreignDimensionalCut.getIdDimensionalCut());
                        ComparatorDimensionalCut foreignComparatorDimensionalCut = delegate.findComparatorDimensionalCut(foreignComparator, foreignDimensionalCut, date);

                        if (foreignComparatorDimensionalCut != null) {
                            //System.out.println("foreignComparatorDimensionalCut ID!!! ES: " + foreignComparatorDimensionalCut.getIdComparatorDimensionalCut());
                            //System.out.println("Value: " + foreignComparatorDimensionalCut.getRegister());
                            dimensionalCutValues.put(foreignDimensionalCut, foreignComparatorDimensionalCut.getRegister());
                        }
                    }
                    /*
                    ComparatorDimensionalCut comparatorDimensionalCut = delegate.findComparatorDimensionalCut(comparator, dimensionalCut, date);
                    if(comparatorDimensionalCut != null){

                    }*/
                }
                dateDimensionalCutValues.put(date, dimensionalCutValues);
            }
            pointerDateDimensionalCutValues.put(foreignPointer, dateDimensionalCutValues);
        }
        return pointerDateDimensionalCutValues;
    }

    public static void getTaskMap(Map<Task, List<Task>> tasks, Task rootTask, DelegateBSC delegate) {
        List<Task> milestones = delegate.findTask(rootTask);
        if (!milestones.isEmpty()) {
            tasks.put(rootTask, milestones);
            for (Task task : milestones) {
                BSCUtils.getTaskMap(tasks, task, delegate);
            }
        }
    }

    public static void setSessionContent(HttpServletRequest request, DelegateBSC delegate, Person person) {
        HttpSession session = request.getSession(true);
        /*List<ScoreDomain> scoreDomains = delegate.findScoreDomain(person);
        session.setAttribute("scoresDomains", scoreDomains);
        session.setAttribute("currentScoreDomain", scoreDomains.get(0));*/
        Framework framework = delegate.findFramework(true);
        session.setAttribute("person", person);
        session.setAttribute("date", ScoreCardUtils.getLastDate());
        session.setAttribute("framework", framework);
        session.setAttribute("frameworkId", framework.getIdFramework());
        /*Framework currentFramework = delegate.findFramework(true);
        List<Comparation> comparations = delegate.findComparation(currentFramework, true);
        for (Comparation comparation : comparations)
        if (comparation.getType().equals(Type.GOAL)) {
        session.setAttribute("comparation", comparation);
        break;
        }*/
    }

    public static void setSessionContent(HttpServletRequest request, DelegateBSC delegate, PersonScoreDomain personScoreDomain) {
        HttpSession session = request.getSession(true);
        PersonScoreDomain.Profile profile = personScoreDomain.getProfile();
        session.setAttribute("profile", profile);
        Person person = personScoreDomain.getPerson();
        switch (profile) {
            case ADMINISTRATOR:
                break;
            case DESIGNER:
                break;
            case DATA_MANAGER:
                break;
            case CORE_TEAM:
            case FINAL_USER:
                List<ScoreDomain> scoreDomains = delegate.findScoreDomain(person);
                session.setAttribute("scoresDomains", scoreDomains);
                session.setAttribute("currentScoreDomain", personScoreDomain.getScoreDomain());
                //session.setAttribute("person", person);
                //session.setAttribute("date", ScoreCardUtils.getLastDate());
                Framework currentFramework = delegate.findFramework(true);
                List<Comparation> comparations = delegate.findComparation(currentFramework, true);
                for (Comparation comparation : comparations) {
                    if (comparation.getType().equals(Type.GOAL)) {
                        session.setAttribute("comparation", comparation);
                        break;
                    }
                }
                break;
        }
    }

    public static String getURI(HttpServletRequest request, PersonScoreDomain personScoreDomain) {
        PersonScoreDomain.Profile profile = personScoreDomain.getProfile();
        switch (profile) {
            case DESIGNER:
                return request.getContextPath() + "/mainDesigner.do";
            case ADMINISTRATOR:
                return request.getContextPath() + "/listFramework.do";
            case CORE_TEAM:
            case FINAL_USER:
                return request.getContextPath() + "/mainFinalUser.do";
            case DATA_MANAGER:
                return request.getContextPath() + "/mainLoadData.do";
        }
        return "../index";
    }

    public static Double getExpectedTime(DelegateBSC delegate, SRM srm) {
        if (srm == null) {
            return 0.0D;
        }
        double estimatedTime = 0.0D;
        List<SRMTopic> srmTopics = delegate.findSRMTopic(srm);
        for (SRMTopic topic : srmTopics) {
            estimatedTime += topic.getExpectedTime();
        }
        return Double.parseDouble((int) estimatedTime / 60 + "." + (int) estimatedTime % 60);
    }

    public static String getServerPath(HttpServletRequest request) {
        return "http://" + request.getServerName() + ":" + request.getServerPort();
    }

    public static boolean hasLicense() {
        DelegateBSC delegate = (DelegateBSC) Factory.getBean("DelegateBSC");
        License currentLicense = delegate.findCurrentLicense();

        return currentLicense != null;
        // return true;
    }
    /*
    public static void addDimensionalCutMember(HttpServletRequest request, DelegateBSC delegate, DimensionMember dimensionMember, DimensionalCut dimensionalCut ){
    DimensionalCutMember dimensionalCutMember = (DimensionalCutMember) Factory.getBean("DimensionalCutMember");
    DimensionMember dimensionMember = delegate.findDimensionMember(Long.parseLong(idDimensionMember));

    if (dimensionMember.getType() == DimensionalCut.Type.STANDARD) {
    isTotal = false;
    }

    dimensionalCutMember.setDimensionMember(dimensionMember);
    dimensionalCutMember.setDimensionalCut(dimensionalCut);


    delegate.createDimensionalCutMember(dimensionalCutMember);
    }
     */

    public static List<ScoreDomain> getAllPersonScoreDomains(DelegateBSC delegate, Person person) {
        List<ScoreDomain> trueScoreDomains = delegate.findScoreDomain(person, Boolean.TRUE);
        List<ScoreDomain> falseScoreDomains = delegate.findScoreDomain(person, Boolean.FALSE);
        List<ScoreDomain> scoreDomains = new ArrayList();

        for (ScoreDomain scoreDomain : trueScoreDomains) {
            scoreDomains.add(scoreDomain);
        }

        for (ScoreDomain scoreDomain : falseScoreDomains) {
            scoreDomains.add(scoreDomain);
        }

        return scoreDomains;
    }

    //Vision 1.5
    public static void normalUpdateDate(POIFSFileSystem fs, DelegateBSC delegate) throws Exception {

        HSSFWorkbook wb = new HSSFWorkbook(fs);
        int sheets = wb.getNumberOfSheets();

        for (int s = 0; s < sheets; s++) {

            //Hoja de trabajo
            //String ht= nombreKPI.substring(0,nombreKPI.length()-4 );
            HSSFSheet sheet = wb.getSheetAt(s);
            String ht = sheet.getSheetName();
            //System.out.println("Hoja: " + ht);

            //Get id Pointer
            HSSFRow rowPointer = sheet.getRow(0);
            Long idPointer = (long) rowPointer.getCell(1).getNumericCellValue();
            Pointer pointer = (Pointer) delegate.findScoreCard(idPointer);
            //System.out.println("Pointer: " + pointer.getName());


            //Get Comaparator
            HSSFRow rowComparator = sheet.getRow(1);
            Long idComparator = (long) rowComparator.getCell(1).getNumericCellValue();
            //System.out.println("El id del comparador es: " + idComparator);
            Comparator comparator = delegate.findComparator(idComparator);
            //System.out.println("Comparador: " + comparator.getDescription());

            //Obtengo la lista de cortes
            List<DimensionalCut> dimensionalCuts = new ArrayList<DimensionalCut>();

            HSSFRow rowCuts = sheet.getRow(3);
            int rowCutsNumber = rowCuts.getLastCellNum();

            for (int i = 1; i < rowCutsNumber; i++) {
                String cutsIdDescription[] = rowCuts.getCell(i).getStringCellValue().split("-");
                Long idDimensionalCut = Long.parseLong(cutsIdDescription[0]);
                DimensionalCut dimensionalCut = delegate.findDimensionalCut(idDimensionalCut);
                dimensionalCuts.add(dimensionalCut);
            }

            //Obtengo la lista de dates

            List<Date> dates = new ArrayList<Date>();
            Map<Date, HSSFRow> dateRow = new HashMap<Date, HSSFRow>();

            int inicioFechas = 4;
            int finFechas = sheet.getLastRowNum();

            //System.out.println("Fin Fechas: " + finFechas);

            for (int i = inicioFechas; i < finFechas + 1; i++) {
                HSSFRow rowDate = sheet.getRow(i);

                Date date = rowDate.getCell(0).getDateCellValue();

                if (ScoreCardUtils.checkDate(date, pointer)) {
                    dates.add(date);
                    dateRow.put(date, rowDate);
                }

            }
            //System.out.println("tam dates: " + dates.size());
            //Se agregan los datos
            for (int i = 0; i < dates.size(); i++) {
                Date date = dates.get(i);
                for (int j = 0; j < dimensionalCuts.size(); j++) {
                    DimensionalCut dimensionalCut = dimensionalCuts.get(j);
                    HSSFRow rowData = dateRow.get(date);
                    HSSFCell rowCell = rowData.getCell(j + 1, HSSFRow.CREATE_NULL_AS_BLANK);
                    //System.out.println("Valor de la celda: " + rowCell.getStringCellValue());
                    //System.out.println("Obtuve el cell");
                    //System.out.println("Fecha: " + date.toString());
                    //System.out.println("Corte: " + dimensionalCut.getIdDimensionalCut());

                    //if (!rowCell.getStringCellValue().equals("")) {
                    if (rowCell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
                        //System.out.println("Obtendré el dato");
                        double data = rowData.getCell(j + 1).getNumericCellValue();
                        data = BSCUtils.roundNumber(data, 2);
                        
                        ComparatorDimensionalCut comparatorDimensionalCut = delegate.findComparatorDimensionalCut(comparator, dimensionalCuts.get(j), date);
                        if (comparatorDimensionalCut == null) {
                            ComparatorDimensionalCut cdc = (ComparatorDimensionalCut) Factory.getBean("ComparatorDimensionalCut");
                            cdc.setComparator(comparator);
                            cdc.setDimensionalCut(dimensionalCut);
                            cdc.setRegisterDate(date);
                            cdc.setRegister(data);

                            delegate.createComparatorDimensionalCut(cdc);
                            //System.out.println("Subi data: " + data);
                            } else {
                            comparatorDimensionalCut.setRegister(data);

                            delegate.updateComparatorDimensionalCut(comparatorDimensionalCut);
                            //System.out.println("Subi data: " + data);

                        }
                    } else if (rowCell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
                        String data = rowData.getCell(j + 1).getStringCellValue();
                        data = data.toUpperCase();
                        if (data.equals("NA")) {
                            ComparatorDimensionalCut comparatorDimensionalCut = delegate.findComparatorDimensionalCut(comparator, dimensionalCuts.get(j), date);
                            if (comparatorDimensionalCut != null) {
                                delegate.deleteComparatorDimensionalCut(comparatorDimensionalCut);
                            }
                        }
                    }
                }
            }
        }
    }

    public static boolean calculateScoreCard(DelegateBSC delegate, Pointer pointer, List<Date> dates) {
        boolean result = true;
        try {
            //System.out.println("Entre a calcular");
            //CÁLCULO!!!
            Framework framework = delegate.findFramework(Boolean.TRUE);

            List<Comparation> comparations = delegate.findComparation(framework, Boolean.TRUE);

            Settings settings = pointer.getSettings();

            if (settings.getOperationData() == Settings.OperationData.CONSOLIDATESUM || settings.getOperationData() == Settings.OperationData.CONSOLIDATEAVG) {
                for (Comparation comparation : comparations) {
                    //Obtenemos las fechas validas para hacer consolidación
                    List<Date> avaliableDates = BSCUtils.isParentComparatorDimenalCutDatesExecutable(delegate, pointer, comparation, dates);
                    //System.out.println("Número de fechas available: " + avaliableDates.size());
                    BSCUtils.setParentComparatorDimensionalCut(delegate, pointer, comparation, avaliableDates);
                }
            } else if (settings.getOperationData() == Settings.OperationData.CALCULATE) {
                for (Comparation comparation : comparations) {
                    BSCUtils.setComparatorDimensionalCut(delegate, comparation, pointer, dates);
                }
            }

            return result;

        } catch (Exception e) {
            e.printStackTrace();
            return result = false;
        }
    }

    public static Double roundNumber (Double register, int decimals){
        
        return Math.round(register*Math.pow(10,decimals))/Math.pow(10,decimals);
    }
}
